{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [],
   "source": [
    "#coding=utf-8\n",
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = pd.read_csv('triplet_dataset_sub_song_merged.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>listen_count</th>\n",
       "      <th>title</th>\n",
       "      <th>release</th>\n",
       "      <th>artist_name</th>\n",
       "      <th>year</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOADQPP12A67020C82</td>\n",
       "      <td>12</td>\n",
       "      <td>You And Me Jesus</td>\n",
       "      <td>Tribute To Jake Hess</td>\n",
       "      <td>Jake Hess</td>\n",
       "      <td>2004</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOAFTRR12AF72A8D4D</td>\n",
       "      <td>1</td>\n",
       "      <td>Harder Better Faster Stronger</td>\n",
       "      <td>Discovery</td>\n",
       "      <td>Daft Punk</td>\n",
       "      <td>2007</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOANQFY12AB0183239</td>\n",
       "      <td>1</td>\n",
       "      <td>Uprising</td>\n",
       "      <td>Uprising</td>\n",
       "      <td>Muse</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOAYATB12A6701FD50</td>\n",
       "      <td>1</td>\n",
       "      <td>Breakfast At Tiffany's</td>\n",
       "      <td>Home</td>\n",
       "      <td>Deep Blue Something</td>\n",
       "      <td>1993</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOBOAFP12A8C131F36</td>\n",
       "      <td>7</td>\n",
       "      <td>Lucky (Album Version)</td>\n",
       "      <td>We Sing.  We Dance.  We Steal Things.</td>\n",
       "      <td>Jason Mraz &amp; Colbie Caillat</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                       user                song  listen_count  \\\n",
       "0  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOADQPP12A67020C82            12   \n",
       "1  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOAFTRR12AF72A8D4D             1   \n",
       "2  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOANQFY12AB0183239             1   \n",
       "3  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOAYATB12A6701FD50             1   \n",
       "4  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOBOAFP12A8C131F36             7   \n",
       "\n",
       "                           title                                release  \\\n",
       "0               You And Me Jesus                   Tribute To Jake Hess   \n",
       "1  Harder Better Faster Stronger                              Discovery   \n",
       "2                       Uprising                               Uprising   \n",
       "3         Breakfast At Tiffany's                                   Home   \n",
       "4          Lucky (Album Version)  We Sing.  We Dance.  We Steal Things.   \n",
       "\n",
       "                   artist_name  year  \n",
       "0                    Jake Hess  2004  \n",
       "1                    Daft Punk  2007  \n",
       "2                         Muse     0  \n",
       "3          Deep Blue Something  1993  \n",
       "4  Jason Mraz & Colbie Caillat     0  "
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.head()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 10774558 entries, 0 to 10774557\n",
      "Data columns (total 7 columns):\n",
      "user            object\n",
      "song            object\n",
      "listen_count    int64\n",
      "title           object\n",
      "release         object\n",
      "artist_name     object\n",
      "year            int64\n",
      "dtypes: int64(2), object(5)\n",
      "memory usage: 575.4+ MB\n"
     ]
    }
   ],
   "source": [
    "data.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 66207 entries, 40085 to 10763546\n",
      "Data columns (total 7 columns):\n",
      "user            66207 non-null object\n",
      "song            66207 non-null object\n",
      "listen_count    66207 non-null int64\n",
      "title           66207 non-null object\n",
      "release         66207 non-null object\n",
      "artist_name     66207 non-null object\n",
      "year            66207 non-null int64\n",
      "dtypes: int64(2), object(5)\n",
      "memory usage: 4.0+ MB\n"
     ]
    }
   ],
   "source": [
    "user_count_df = pd.read_csv('user_playcount_df.csv')\n",
    "user_count_subset = user_count_df.head(n=200)\n",
    "user_subset = list(user_count_subset.user)\n",
    "data_sub1 = data[data.user.isin(user_subset)]\n",
    "data_sub1.info()\n",
    "data_sub1=data_sub1.drop('title',axis=1)\n",
    "data_sub1=data_sub1.drop('release',axis=1)\n",
    "data_sub1=data_sub1.drop('artist_name',axis=1)\n",
    "data_sub1=data_sub1.drop('year',axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import defaultdict\n",
    "data_sub1.head()\n",
    "asongsForUser = defaultdict(set)\n",
    "ausersForSong = defaultdict(set)\n",
    "for k in data_sub1.index: \n",
    "    asongsForUser[data_sub1.loc[k,'user']].add(data_sub1.loc[k,'song'])    #该用户听过这个歌曲\n",
    "    ausersForSong[data_sub1.loc[k,'song']].add(data_sub1.loc[k,'user'])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn import preprocessing \n",
    "import scipy.sparse as ss\n",
    "import scipy.spatial.distance as ssd\n",
    "import numpy\n",
    "from collections import defaultdict\n",
    "import itertools\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_sub, test = train_test_split(data_sub1, test_size = 0.40, random_state=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 39724 entries, 2871914 to 6693310\n",
      "Data columns (total 3 columns):\n",
      "user            39724 non-null object\n",
      "song            39724 non-null object\n",
      "listen_count    39724 non-null int64\n",
      "dtypes: int64(1), object(2)\n",
      "memory usage: 1.2+ MB\n"
     ]
    }
   ],
   "source": [
    "#train.head()\n",
    "data_sub.info()\n",
    "x=data_sub.values\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "#用户列表与歌曲列表\n",
    "x=data_sub['user']\n",
    "uniqueUsers = set(x)\n",
    "x=data_sub['song']\n",
    "uniqueSongs =  set(x)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hi\n"
     ]
    }
   ],
   "source": [
    "userIndex = dict()\n",
    "songIndex = dict()\n",
    "#重新编码用户索引字典\n",
    "for i, u in enumerate(uniqueUsers):\n",
    "    userIndex[u] = i\n",
    "    \n",
    "#重新编码活动索引字典    \n",
    "for i, e in enumerate(uniqueSongs):\n",
    "    songIndex[e] = i\n",
    "print('hi')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hi\n",
      "hi\n"
     ]
    }
   ],
   "source": [
    "#构造用户与歌曲矩阵\n",
    "nusers=len(uniqueUsers)\n",
    "nsongs=len(uniqueSongs)\n",
    "userSongscount = ss.dok_matrix((nusers, nsongs),dtype=numpy.float64)\n",
    "print('hi')\n",
    "\n",
    "#形成用户与歌曲打分矩阵  \n",
    "for i in data_sub.index:\n",
    "    userSongscount[userIndex[data_sub.loc[i,'user']],songIndex[data_sub.loc[i,'song']]]=data_sub.loc[i,'listen_count']\n",
    "print('hi')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hi\n"
     ]
    }
   ],
   "source": [
    "s_scaler=preprocessing.StandardScaler(copy=True, with_mean=False, with_std=True)\n",
    "x_train=s_scaler.fit_transform(userSongscount)\n",
    "x_train=x_train*10\n",
    "print('hi')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hi\n"
     ]
    }
   ],
   "source": [
    "from collections import defaultdict\n",
    "songsForUser = defaultdict(set)\n",
    "usersForSong = defaultdict(set)\n",
    "for k in data_sub.index: \n",
    "    i= userIndex[data_sub.loc[k,'user']]  #用户\n",
    "    j = songIndex[data_sub.loc[k,'song']] #歌曲\n",
    "    #print(train.loc[k,'user'])\n",
    "   \n",
    "    songsForUser[i].add(j)    #该用户听过这个歌曲\n",
    "    usersForSong[j].add(i)\n",
    "    \n",
    "print('hi')\n",
    "\n",
    "         "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hi\n",
      "16293\n"
     ]
    }
   ],
   "source": [
    "import itertools\n",
    "uniqueUserPairs = set()\n",
    "uniqueSongPairs = set()\n",
    "for song in uniqueSongs:\n",
    "    i = songIndex[song]\n",
    "    users = usersForSong[i]\n",
    "    if len(users) > 2:\n",
    "        uniqueUserPairs.update(itertools.combinations(users, 2))\n",
    "for user in uniqueUsers:\n",
    "    u = userIndex[user]\n",
    "    songs = songsForUser[u]\n",
    "    if len(songs) > 2:\n",
    "        uniqueSongPairs.update(itertools.combinations(songs, 2))  \n",
    "print('hi')\n",
    "print(len(uniqueUserPairs))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hi\n"
     ]
    }
   ],
   "source": [
    "usersim=ss.dok_matrix((nusers, nusers))\n",
    "def sim_cal(uid1, uid2):\n",
    "        if  ((uid1,uid2) in usersim):  #如果已经计算好\n",
    "            return usersim[uid1,uid2]          \n",
    "        if  (uid1,uid2) in uniqueUserPairs: \n",
    "            usim = ssd.correlation(userSongscount.getrow(uid1).todense(),\n",
    "            userSongscount.getrow(uid2).todense())             \n",
    "            usersim[uid1, uid2] = usim\n",
    "            usersim[uid2, uid1] = usim        \n",
    "        if  not((uid1,uid2) in usersim):\n",
    "            return 0\n",
    "        return usersim[uid1,uid2]\n",
    "\n",
    "    \n",
    "print('hi')               "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hi\n"
     ]
    }
   ],
   "source": [
    "def pred(uid,sid):  \n",
    "        sim_accumulate=0.0  \n",
    "        rat_acc=0.0  \n",
    "      #  if sid>nsongs:\n",
    "      #     return 0\n",
    "       # if uid>nusers:\n",
    "       #     return 0\n",
    "        for user in usersForSong[sid]:  #对i_id打过分的所有用户\n",
    "            sim = sim_cal(uid,user)    #该user与uid之间的相似度\n",
    "            #print('sim%f'%sim)\n",
    "            #print(userSongscount[user,sid])\n",
    "            if sim<=0:continue  \n",
    "            #print sim,self.user_movie[uid][item],sim*self.user_movie[uid][item]  \n",
    "            rat_acc += sim *userSongscount[user,sid] \n",
    "            sim_accumulate += sim \n",
    "\n",
    "        if sim_accumulate==0: #no same user rated,return 0 \n",
    "            return  0\n",
    "        return int(round(rat_acc/sim_accumulate))\n",
    "\n",
    "print('hi')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [],
   "source": [
    "def testdata(u):\n",
    "    output={}\n",
    "    if not( u  in uniqueUsers):\n",
    "         for song in uniqueSongs:\n",
    "          output[song]=0\n",
    "    else:\n",
    "        for song in uniqueSongs:\n",
    "            i=pred(userIndex[u],songIndex[song])\n",
    "            output[song]=i\n",
    "   \n",
    "        \n",
    "    return output\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 26483 entries, 4648114 to 9031252\n",
      "Data columns (total 3 columns):\n",
      "user            26483 non-null object\n",
      "song            26483 non-null object\n",
      "listen_count    26483 non-null int64\n",
      "dtypes: int64(1), object(2)\n",
      "memory usage: 827.6+ KB\n"
     ]
    }
   ],
   "source": [
    "\n",
    "test.info()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "16\n",
      "26483\n",
      "3800\n",
      "准确率0.004211\n",
      "召回率0.000604\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'\\nprint(\\'jjjj\\')\\n#p=tp/(tp+fp)\\n#if(tp+fn)==0:\\n #   r=0\\n#else:\\n #   r=tp/(tp+fn)\\n        c\\n#print(\"准确率%f\"%p)\\n        \\n#print(\"召回率%f\"%r)\\n'"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "at=0\n",
    "aj=0\n",
    "tp=0\n",
    "\n",
    "\n",
    "uniqueUsers2=set(test['user'])\n",
    "songsforUsers2=defaultdict(set)\n",
    "for k in test.index: \n",
    "    songsforUsers2[test.loc[k,'user']].add(test.loc[k,'song'])\n",
    "\n",
    "for u in uniqueUsers2:\n",
    "    q=testdata(u)\n",
    "    q=sorted(q.items(),key = lambda x:x[1],reverse = True)\n",
    "    i=0\n",
    "    tsq=dict(q[0:19])\n",
    "    sq=set()\n",
    "    for key,value in tsq.items():\n",
    "        sq.add(key)\n",
    "\n",
    "    ssong=set(songsforUsers2[u])\n",
    "    tp=len(sq.intersection(ssong))+tp\n",
    "    at=len(ssong)+at\n",
    "    aj=aj+len(sq) \n",
    "        \n",
    "        \n",
    "print(tp)\n",
    "print(at)\n",
    "print(aj)\n",
    "          \n",
    "p=tp/aj\n",
    "r=tp/at\n",
    "print(\"准确率%f\"%p)\n",
    "print(\"召回率%f\"%r)\n",
    "#  print([test1[i][0]])\n",
    "       # print(s)\n",
    "       # print('hi')\n",
    "       # print(songIndex[s])\n",
    "        #if songIndex[s] in songsForUser[userIndex[test1[i][0]]]:\n",
    "         #   score=userSongscount[userIndex[test1[i][0]],songIndex[s]]\n",
    "        #else:\n",
    "'''\n",
    "        if  u not in uniqueUsers:\n",
    "            score=0\n",
    "        else:\n",
    "            if s not in uniqueSongs :\n",
    "                score=0\n",
    "            else:    \n",
    "                score=testdata(userIndex[u],songIndex[s])\n",
    "        #print(\"hhi%f\"%score)\n",
    "    if score>0 :\n",
    "        if songIndex2[s] in songs :\n",
    "            tp=tp+1\n",
    "        else:\n",
    "            fp=fp+1\n",
    "        \n",
    "    else:\n",
    "        if songIndex2[s] in songs :\n",
    "            fn=fn+1\n",
    "        else:\n",
    "            tn=tn+1\n",
    "'''\n",
    "\n",
    "'''\n",
    "print('jjjj')\n",
    "#p=tp/(tp+fp)\n",
    "#if(tp+fn)==0:\n",
    " #   r=0\n",
    "#else:\n",
    " #   r=tp/(tp+fn)\n",
    "        c\n",
    "#print(\"准确率%f\"%p)\n",
    "        \n",
    "#print(\"召回率%f\"%r)\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
